package utils;

import static org.junit.Assert.*;

import org.junit.Test;

import parser.Constants;
import parser.IupacBranch;
import parser.IupacParser;
import parser.IupacResidue;

public class TreeToolsTest extends TreeTools {

//	String input = "Me(-3)Rha(a1-4){Man(b1-3)Rha(a1-4)}26Man(a1-3)Rha(a1-3)Rha(a1-3)Rha(a1-3)Gal";
//	IupacParser p= new IupacParser(input);
//	try {
//		p.parse();
//	} catch (Exception ex) {		
//		ex.printStackTrace();
//	}
//	System.out.println(p.getCtSequence());
	
	@Test
	public void testGetRootBranch() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		IupacBranch b = p.getTree().getBranches().get(0);
		assertTrue((getRootBranch(p.getTree().getBranches())).equals(b));	
	}

	@Test
	public void testGetParentBranchId() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		IupacBranch b0 = p.getTree().getBranches().get(0);
		IupacBranch b1 = p.getTree().getBranches().get(1);
		IupacBranch b2 = p.getTree().getBranches().get(2);
		IupacBranch b3 = p.getTree().getBranches().get(3);
		IupacBranch b4 = p.getTree().getBranches().get(4);
		
		assertTrue((getParentBranchId(b1)).equals(b0.getId()));
		assertTrue((getParentBranchId(b2)).equals(b0.getId()));
		assertTrue((getParentBranchId(b3)).equals(b2.getId()));
		assertTrue((getParentBranchId(b4)).equals(b2.getId()));
	}

	@Test
	public void testGetChildrenBranchIds() {
//		TODO
	}

	@Test
	public void testGetChildrenBranchesNotInSortedTree() {
//		TODO
	}

	@Test
	public void testGetChildrenBranchesIupacBranchArrayListOfIupacBranch() {
//		TODO
	}

	@Test
	public void testGetChildrenBranchesArrayListOfStringArrayListOfIupacBranch() {
//		TODO
	}

	@Test
	public void testGetParentBranchIupacBranchArrayListOfIupacBranch() {
//		TODO
	}

	@Test
	public void testGetBranchFromBranchId() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		IupacBranch b = p.getTree().getBranches().get(0);
		assertTrue(getBranchFromBranchId(b.getId(), b.getTree().getBranches()).equals(b));
	}

	@Test
	public void testHasChildrenBranches() {
//		TODO
	}

	@Test
	public void testIsBranchInSortedTree() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		IupacBranch b = p.getTree().getBranches().get(3);
		assertTrue(isBranchInSortedTree(b, b.getTree().getBranches()));
	}

//	@Test
//	public void testArrayIdInLine() {
//		fail("Not yet implemented");
//	}

	@Test
	public void testGetFirstResidue() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		int index = 2;
		IupacBranch b = p.getTree().getBranches().get(index);
		IupacResidue r = b.getResiduesList().get(0);
		assertTrue((getFirstResidue(b)).equals(r));
	}

	@Test
	public void testGetLastResidue() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		int index = 2;
		IupacBranch b = p.getTree().getBranches().get(index);
		IupacResidue r = b.getResiduesList().get(b.getResiduesList().size()-1);
		assertTrue((getLastResidue(b)).equals(r));
	}

	@Test
	public void testGetIdxResidue() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		int index = 2;
		IupacBranch b = p.getTree().getBranches().get(index);
		IupacResidue r = b.getResiduesList().get(0);
		assertTrue((getBranchFromResidueId(r.getId(),p.getTree().getBranches())).equals(b));
	}

	@Test
	public void testGetPreviousResidueIntIntArrayListOfIupacBranch() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]Man(a1-?)GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		int index = 2;
		IupacBranch b = p.getTree().getBranches().get(index);
		IupacResidue rlast = getLastResidue(b); //Man(b1-4)
		IupacResidue rfirst = getFirstResidue(b); //GlcNAc(b1-4)
		IupacResidue rootresidue = p.getTree().getBranches().get(0).getResidue(0);
		
		IupacResidue rmiddle = getPreviousResidue(b.getTree().getBranches().indexOf(b), b.getResiduesList().indexOf(rfirst), b.getTree().getBranches());
		
		System.err.println("test on last residue of a branch, current : " + rlast.getId() + ", previous : " +getPreviousResidue(b.getTree().getBranches().indexOf(b), b.getResiduesList().indexOf(rlast), b.getTree().getBranches()).getId());
		System.err.println("test on first residue of a branch, current : " + rfirst.getId() + ", previous : " +getPreviousResidue(b.getTree().getBranches().indexOf(b), b.getResiduesList().indexOf(rfirst), b.getTree().getBranches()).getId());
		System.err.println("test on root, current : " + rootresidue.getId() + ", previous : " +getPreviousResidue(rootresidue.getBranch().getTree().getBranches().indexOf(rootresidue.getBranch()), rootresidue.getBranch().getResiduesList().indexOf(rootresidue), rootresidue.getBranch().getTree().getBranches()).getId());
		//System.err.println("test on root, current : " + rootresidue.getSequence() + ", previous : " +getPreviousResidue(rootresidue.getBranch().getTree().getBranches().indexOf(b), b.getResiduesList().indexOf(rootresidue), b.getTree().getBranches()).getSequence());
		
		
		boolean test1 = (getPreviousResidue(b.getTree().getBranches().indexOf(b), b.getResiduesList().indexOf(rlast), b.getTree().getBranches())).equals(rfirst);
		boolean test2 = (getPreviousResidue(b.getTree().getBranches().indexOf(b), b.getResiduesList().indexOf(rfirst), b.getTree().getBranches())).equals(rmiddle);
		boolean test3 = (getPreviousResidue(rmiddle.getBranch().getTree().getBranches().indexOf(rmiddle.getBranch()), b.getResiduesList().indexOf(rmiddle), rmiddle.getBranch().getTree().getBranches()).equals(rootresidue));
		
		assertTrue(test1);
		assertTrue(test2);
		assertTrue(test3);
	}

	@Test
	public void testGetPreviousResidueIupacResidue() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]Man(a1-?)GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		int index = 2;
		IupacBranch b = p.getTree().getBranches().get(index);
		IupacResidue rlast = getLastResidue(b); //Man(b1-4)
		IupacResidue rfirst = getFirstResidue(b); //GlcNAc(b1-4)
		IupacResidue rootresidue = p.getTree().getBranches().get(0).getResidue(0);
		
		IupacResidue rmiddle = getPreviousResidue(b.getTree().getBranches().indexOf(b), b.getResiduesList().indexOf(rfirst), b.getTree().getBranches());
		
		boolean test1 = (getPreviousResidue(rlast)).equals(rfirst);
		boolean test2 = (getPreviousResidue(rfirst)).equals(rmiddle);
		boolean test3 = (getPreviousResidue(getPreviousResidue(rfirst)).equals(rootresidue));
		
		assertTrue(test1);
		assertTrue(test2);
		assertTrue(test3);
		
	}

	@Test
	public void testGetParentBranchStringArrayListOfIupacBranch() {
//		TODO?
//		fail("Not yet implemented");
	}

	@Test
	public void testGetBranchFromResidueId() {
		String input = "Ara(?1-?)[GlcNAc(b1-?)]Man(a1-?)[Man(a1-?)][Xyl(?1-?)]Man(b1-4)GlcNAc(b1-4)[Fuc(?1-?)]GlcNAc";
		IupacParser p= new IupacParser(input);
		try {
			p.parse();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		int index = 2;
		IupacBranch b = p.getTree().getBranches().get(index);
		IupacResidue r = b.getResiduesList().get(0);
		assertTrue(getBranchFromResidueId(r.getId(),p.getTree().getBranches()).equals(b));
	}

	@Test
	public void testHasRepeatChar() {
		String input = "Me(-3)Rha(a1-4){Man(b1-3)Rha(a1-4)}26Man(a1-3)Rha(a1-3)Rha(a1-3)Rha(a1-3)Gal";
		assertTrue(TreeTools.hasRepeatChar(input));
	}

	@Test
	public void testHasCommentChar() {
		String input = "Gal(b1-4)[Glc(a1-6)]ManNAc(b1-3){Gal(b1-4)[Glc(a1-6)]ManNAc}j(b1-3)Gal(b1-4)[Glc(a1-6)]ManNAc(a1-3)[GroA2(u?-?)P(u?-4)Man(b1-4)]Rha(a1-3)Rha(a1-3)Rha(a1-3)Gal+"+Constants.doubleQuote+"where j = 20"+Constants.doubleQuote;
		assertTrue( TreeTools.hasRepeatChar(input));
	}

	@Test
	public void testGetMultitude() {
		String input1 = "{}26";
		String input2 = "Me(-3)Rha(a1-4){Man(b1-3)Rha(a1-4)}26Man(a1-3)Rha(a1-3)Rha(a1-3)Rha(a1-3)Gal";
		//System.err.println("getMultitude(input, 1) : " + getMultitude(input, 1));
		assertTrue(getMultitude(input1, 1).equals("26"));
		System.out.println("GetMultitude : " + getMultitude(input2, input2.lastIndexOf(Constants.closingCurlyBracket)));
		assertTrue(getMultitude(input2, input2.lastIndexOf(Constants.closingCurlyBracket)).equals("26"));
	}

	@Test
	public void testRemoveBrackets() {
		String test = "b1-4";
		assertTrue(removeBrackets((Constants.openingParenthesis +test+Constants.closingParenthesis)).equals(test));
	}

	@Test
	public void testIsRepeatSequence() {
		String input = "Me(-3)Rha(a1-4){Man(b1-3)Rha(a1-4)}26Man(a1-3)Rha(a1-3)Rha(a1-3)Rha(a1-3)Gal";
		assertTrue(isRepeatSequence(input));
	}

}
